#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include<string>
#include<iostream>
#include<stack>
#include<vector>
using namespace std;

enum nonterminal { S, B, C, E, E1, A, T, T1, M, F, L };

string m_map[11] = { "S","B","C","E","E1","A","T","T1","M","F","L" };
vector<string>yans;

struct item {
	item(string s, int t) { name = s; type = t; }
	string name;
	int type;
};

struct KeyWords {
	string sign;
	string desp;
	int number;
};
//struct KeyWords {
//	string sign;
//	string desp;
//	int number;
//};

stack<item>st;

int parsetable[11][17] = {
	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,0,-1},
	{-1,2,-1,-1,-1,2,-1,-1,-1,-1,-1,-1,-1,2,2,-1,-1},
	{-1,-1,-1,-1,-1,-1,-1,3,4,5,6,7,8,-1,-1,-1,-1},
	{-1,9,-1,-1,-1,9,-1,-1,-1,-1,-1,-1,-1,9,9,-1,-1},
	{10,10,-1,-1,-1,-1,11,11,11,11,11,11,11,-1,-1,-1,11},
	{12,13,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{-1,14,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,14,14,-1,-1},
	{16,16,15,15,15,-1,16,16,16,16,16,16,16,-1,-1,-1,16},
	{-1,-1,17,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
	{-1,21,-1,-1,-1,20,-1,-1,-1,-1,-1,-1,-1,22,23,-1,-1},
	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,-1},
};

int getNumber(KeyWords k)
{
	if (k.desp == "NUM") return 13;
	if (k.desp == "ID") return 14;
	if (k.desp == "OP") return k.number;
	if (k.desp == "RELOP") return k.number + 7;
	if (k.sign == "(") return 5;
	if (k.sign == ")") return 6;
	if (k.desp == "if") return 15;
	if (k.sign == "end") return 16;
	return -1;
}

//KeyWords keywords[4] = {
//	{"ab", "ID", 1 },
//	{"=", "ASSIGNMENT", 0},
//	{"123", "NUM", 123},
//	{"end","end",0},
//};

KeyWords lexCode[10] = {
	{"if","if",3},
	{"(","(",0},
	{"c","ID",3},
	{"==","RELOP",4},
	{"1","NUM",1},
	{")",")",0},
	{"m","ID",4},
	{"=","ASSIGNMENT",0},
	{"1","NUM",1},
	{"end","end",0},
};
/*
{"if","if",3},
{"(","(",0},
{"c","ID",3},
{"==","RELOP",4},
{"1","NUM",1},
{")",")",0},
{"m","ID",4},
{"=","ASSIGNMENT",0},
{"1","NUM",1},
*/


int letterMap(item temp)
{
	for (int i = 0; i < 11; i++)
		if (temp.name == m_map[i])
			return i;
	return -1;
}

int action(int choice)
{
	switch (choice) 
	{
	case 0:{
		yans.push_back("S -> IF(B)S");
		st.pop();
		st.push(item("S", 1));
		st.push(item(")", 0));
		st.push(item("B", 1));
		st.push(item("(", 0));
		st.push(item("if", 0));
		break;
	}
	case 1:
		yans.push_back("S -> L=E");
		st.pop();
		st.push(item("E", 1));
		st.push(item("=", 0));
		st.push(item("L", 1));
		break;
	case 2:
		yans.push_back("S -> EC");
		st.pop();
		st.push(item("C", 1));
		st.push(item("E", 1));
		break;
	case 3:
		yans.push_back("C -> <E");
		st.pop();
		st.push(item("E", 1));
		st.push(item("<", 0));
		break;
	case 4:
		yans.push_back("C -> >E");
		st.pop();
		st.push(item("E", 1));
		st.push(item(">", 0));
		break;
	case 5:
		yans.push_back("C -> <=E");
		st.pop();
		st.push(item("E", 1));
		st.push(item("<=", 0));
		break;
	case 6:
		yans.push_back("C -> >=E");
		st.pop();
		st.push(item("E", 1));
		st.push(item(">=", 0));
		break;
	case 7:
		yans.push_back("C -> ==E");
		st.pop();
		st.push(item("E", 1));
		st.push(item("==", 0));
		break;
	case 8:
		yans.push_back("C -> <>E");
		st.pop();
		st.push(item("E", 1));
		st.push(item("<>", 0));
		break;
	case 9:
		yans.push_back("E -> TE1");
		st.pop();
		st.push(item("E1", 1));
		st.push(item("T", 1));
		break;
	case 10:
		yans.push_back("E1 -> AE1");
		st.pop();
		st.push(item("E1", 1));
		st.push(item("A", 1));
		break;
	case 11:
		yans.push_back("E1 -> #");
		st.pop();
		break;
	case 12:
		yans.push_back("A -> +T");
		st.pop();
		st.push(item("T", 1));
		st.push(item("+", 0));
		break;
	case 13:
		yans.push_back("A -> -T");
		st.pop();
		st.push(item("T", 1));
		st.push(item("-", 0));
		break;
	case 14:
		yans.push_back("T -> FT1");
		st.pop();
		st.push(item("T1", 1));
		st.push(item("F", 1));
		break;
	case 15:
		yans.push_back("T1 -> MT1");
		st.pop();
		st.push(item("T1", 1));
		st.push(item("M", 1));
		break;
	case 16:
		yans.push_back("T1 -> #");
		st.pop();
		break;
	case 17:
		yans.push_back("M -> *F");
		st.pop();
		st.push(item("F", 1));
		st.push(item("*", 0));
		break;
	case 18:
		yans.push_back("M -> /F");
		st.pop();
		st.push(item("F", 1));
		st.push(item("/", 0));
		break;
	case 19:
		yans.push_back("M -> %F");
		st.pop();
		st.push(item("F", 1));
		st.push(item("%", 0));
		break;
	case 20:
		yans.push_back("F -> (E)");
		st.pop();
		st.push(item(")", 0));
		st.push(item("E", 1));
		st.push(item("(", 0));
		break;
	case 21:
		yans.push_back("F -> -F");
		st.pop();
		st.push(item("F", 1));
		st.push(item("-", 1));
		break;
	case 22:
		yans.push_back("F -> NUM");
		st.pop();
		st.push(item("NUM", 0));
		break;
	case 23:
		yans.push_back("F -> L");
		st.pop();
		st.push(item("L", 1));
		break;
	case 24:
		yans.push_back("L -> ID");
		st.pop();
		st.push(item("ID", 0));
		break;
	
	default:
		return -1;
	}
	return 1;
}

int main()
{
	st.push(item("S", 1));

	int i = 0;
	while(!st.empty())
	{
		KeyWords k = lexCode[i];
		int number = getNumber(k);
		item temp = st.top();
		if (temp.type == 0)
		{
			if (temp.name == k.desp|| temp.name==k.sign)
			{
				st.pop();
				i++;
			}
			else
			{
				cout << "error!" << endl;
				break;
			}
		}
		else
		{
			int mapNumber = letterMap(temp);
			int next = parsetable[mapNumber][number];
			int flag = action(next);
			if (flag == -1)
			{
				cout << "error!" << endl;
				break;
			}
		}
	}
	for (int i = 0; i < yans.size(); i++)
	{
		cout << yans[i] << endl;
	}
}
